// ISO1 = VCC
// ISO5 = GND
/*
int ISO2=2; // ISO2 : Read=0 or write=5v 
int ISO3=3; // ISO3 : Clock
int ISO4=4; // ISO4 : Reset
int ISO7=7; // ISO7 : Data
*/
int ISO1=A1; // ISO1 = VCC
int ISO2=A2; // ISO2 : Read=0 or write=5v 
int ISO3=A3; // ISO3 : Clock
int ISO4=A4; // ISO4 : Reset
int ISO7=A0; // ISO7 : Data
volatile int arrach = LOW; // déclartion d'une variable volatile


// ISO6 VPP 5V
/*
16 à 52 : N° de serie
 72 ( 8 bits)  Compteur x 64u
 80 ( 7 bits)  compteur x 8
 87 : 1
 88 ( 7 bits) compteur x 1
 95 : 1 
 96 : Carte vide ?
 112 : à 127 Certificat (16bits)
 */

byte Values[512];
int ValuesHEX[64];
String hashcard;

void setup_Card() {
  pinMode(ISO2, OUTPUT);
  pinMode(ISO3, OUTPUT);
  pinMode(ISO4, OUTPUT);

  pinMode(ISO7, INPUT);

  analogWrite(ISO2, 0);
  analogWrite(ISO3, 0);
  analogWrite(ISO4, 0);
}


void setup() {

    Serial.begin(115200); 


  pinMode(ISO1, OUTPUT);
  analogWrite(ISO1,255); // on alimente la carte

  pinMode(8, OUTPUT);
  analogWrite(8,255);
  
  // put your setup code here, to run once:

  Serial.println("Telecarte Reader : " );                       
  setup_Card();

}
void Clock_Card()
{
  analogWrite(ISO3, 255);
 // delay(3);
  analogWrite(ISO3, 0);
}

// T2G Mod Selection
void reset_mod_Card(){
  analogWrite(ISO2, 0);
  analogWrite(ISO4, 0);
}


void read_mod_Card()
{
  analogWrite(ISO2, 0);
  analogWrite(ISO4, 255);
}

void read_Card()
{
  reset_mod_Card();
  Clock_Card();

  read_mod_Card();

  for(int i=0;i<512;i++)
  {
    Values[i]  = analogRead(ISO7);
    if ( Values[i] > 200 ) Values[i] = 1; else Values[i] = 0;
    Clock_Card();
  }
}


void write_Card()
{
  reset_mod_Card();
  Clock_Card();


  for(int i=0;i<512;i++)
  {
     read_mod_Card();
    if ( i > 230 && i < 240)
    {
      write_mod_Card();
     pinMode(ISO7, OUTPUT);
     Serial.print("ecriture  1 sur : " );  
     Serial.println(i);  

     analogWrite(ISO7,255);
     //else analogWrite(ISO7,0);
    }
    Clock_Card();
  }
       pinMode(ISO7, INPUT);

}


void write_mod_Card()
{
  // ISO 7 : VCC 5V
  analogWrite(ISO2, 255);
  analogWrite(ISO4, 255);
}

void compare_mod_Card()
{
  analogWrite(ISO2, 0);
  analogWrite(ISO4, 255);
}

void export_binary_CAR_format()
{
  for(int i=0;i<512;i++)
  {
    // Serial.print(i);  
    // Serial.print(":");  
    char next;
    if (i % 4 == 0)     
    {
      next=0x20;
      Serial.print(char(next));
      Serial.print(char(next));
    }
    if (i % 32 == 0)     
    {
      next=0x0d;
      Serial.print(char(next));
      next=0x0a;
      Serial.print(char(next)); 
    }
    Serial.print(Values[i]);  

  }
  Serial.println("" ); 
}
int toBin(int Cursor, int Bits = 4)
{
  int value = 0;
  for ( int i=0; i<Bits; i++)
  {
    if ( i!=0)  value =  value << 1;
    value = value +  Values[Cursor+i];
  }
  return value;
}
int GET_POUVOIR_FINANCIER()
{
  return (toBin(60,4)*10);
}
String Bit_to_String(int cursor, int nbchar, int  type = DEC)
{
    String string;
    for (int i=0;i< nbchar; i++)
    {
       string = string + String(toBin(4*i+cursor), type);
    }
    return string;
}
String GET_SERIAL()
{
  return Bit_to_String(16, 9);
}

String GET_APCODE()
{
  return Bit_to_String(0, 4);
}
String GET_ROMZONE()
{
  return Bit_to_String(0, 16, HEX);
}

int GET_UNITES()
{
  int unite = 0;
  for(int i=71;i<79;i++)
  {
    if ( Values[i] == 1)  unite = unite + 64;
  }
  for(int i=79;i<87;i++)
  {
    if ( Values[i] == 1)  unite = unite + 8;
  }
  for(int i=87;i<94;i++)
  {
    if ( Values[i] == 1)  unite = unite + 1;
  }

  if ( unite > 200 ) return 0;
  return unite;
}

void loop() {
  // put your main code here, to run repeatedly: 
  pinMode(8, INPUT);
if ( digitalRead(8) == LOW) 
{
//write_Card();
    analogWrite(ISO1, 255); // Couper VCC
  read_Card();
    analogWrite(ISO1, 0); // Couper VCC


  export_binary_CAR_format();
  // affichage des valeurs en port serie

  // Pouvoir financier

  Serial.print("Zone ROM : " );                       
  Serial.println(GET_ROMZONE() );     

  Serial.print("POUVOIR FINANCIER : " );        
  Serial.print(GET_POUVOIR_FINANCIER());  
  Serial.println(" UNITES" );  
  // consommation d'unité  
  Serial.print("UNITE CONSOMMEES : " );                       
  Serial.println(GET_UNITES() );   
    Serial.print("APCODE : " );                       
  Serial.println(GET_APCODE() ); 
  Serial.print("SERIAL : " );                       
  Serial.println(GET_SERIAL() );     
}
else
{
  Serial.println(" Wait Card ! " );  

}


  delay( 1000);
}






